package academic.ui.server;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import org.apache.torque.NoRowsException;
import org.apache.torque.TooManyRowsException;
import org.apache.torque.TorqueException;
import org.apache.torque.util.Criteria;

import torque.generated.Customers;
import torque.generated.CustomersPeer;
import torque.generated.GroupMember;
import torque.generated.GroupMemberPeer;
import torque.generated.Orders;
import torque.generated.OrdersPeer;

import academic.ui.client.CustomerService;
import academic.ui.client.rules.Rules;
import ecommerce.soco.server.encrypt.Encrypt;
import ecommerce.soco.server.util.email.EmailUsers;
import ecommerce.soco.shared.*;

public class CustomerServiceImpl extends AppServiceImpl implements
		CustomerService {

	private static final long serialVersionUID = -3661924533421139578L;

	/**
	 * Return A GWT_Customer with a default Address included
	 */
	@Override
	public GWT_Customer getCurrentCustomer() {
		Customers customer;
		try {
			customer = CustomersPeer.retrieveByPK(getAppEng().getUserMgr()
					.getCurrentCustomer().getCustomersId());
			return helper.getGWT_Customer(customer);
		} catch (NoRowsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TooManyRowsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TorqueException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public ArrayList<GWT_Purchase> getDealsPurchasedByCustomer() {

		ArrayList<GWT_Purchase> clientPurchases = new ArrayList<GWT_Purchase>();
		try {
			List<Orders> orders = OrdersPeer.doSelect(new Criteria().add(
					OrdersPeer.CUSTOMERS_ID,
					getAppEng().getUserMgr().getCurrentCustomer()
							.getCustomersId()).addDescendingOrderByColumn(
					OrdersPeer.DATE_PURCHASED));

			for (Orders o : orders)
				clientPurchases.add(helper.getGWT_Purchase(o));

		} catch (TorqueException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return clientPurchases;
	}

	@Override
	public ArrayList<GWT_Purchase> getGiftsPurchasedByCustomer() {

		ArrayList<GWT_Purchase> clientOrders = new ArrayList<GWT_Purchase>();

		try {
			OrdersPeer.doSelect(new Criteria().add(
					OrdersPeer.CUSTOMERS_ID,
					getAppEng().getUserMgr().getCurrentCustomer()
							.getCustomersId()).and(OrdersPeer.ORDERS_TYPE,
					"gift").addDescendingOrderByColumn(
					OrdersPeer.DATE_PURCHASED));
		} catch (TorqueException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return clientOrders;
	}

	@Override
	public Boolean login(String username, String passwd) {

		SocoEngine appEng = getAppEng();
		return appEng.getUserMgr().login(username, passwd);

	}

	@Override
	public Integer registerCustomer(GWT_Customer customerRegistration,
			Boolean loginIfUserExists) {
		int custId = -1;
		SocoEngine appEng = getAppEng();
		if (UserManager.customerExists(customerRegistration.getEmailAddr())
				&& !loginIfUserExists)
			return Rules.REGISTER_ERROR_USER_EXISTS;
		custId = appEng.getUserMgr().registerCustomer(customerRegistration,
				appEng.getCity());
		UserManager.updateEmailList(customerRegistration.getEmailAddr());

		login(customerRegistration.getEmailAddr(), customerRegistration
				.getPassword());
		custId = appEng.getUserMgr().getCurrentCustomer().getCustomersId();

		if (custId > -1 && isLoggedIn())
			return Rules.SUCCESS;
		else
			return Rules.LOGIN_ERROR_USER_NOT_FOUND;
	}

	@Override
	public Boolean updateLocation(GWT_Customer customerUpdateAddress) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Boolean updatePersonalInfo(GWT_Customer customerUpdatePersonal) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Boolean updateName(String name) {
		Customers customer = getAppEng().getUserMgr().getCurrentCustomer();
		String[] names = UserManager.getFirstLastFromFull(name);
		if (names.length > 0)
			customer.setFirstname(names[0]);
		if (names.length > 1)
			customer.setLastname(names[1]);
		try {
			customer.save();
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}

	}

	@Override
	public Boolean updateEmail(String email) {
		Customers customer = getAppEng().getUserMgr().getCurrentCustomer();
		customer.setEmailAddress(email);
		try {
			customer.save();
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public Boolean updatePasswd(String oldPass, String newPass) {
		Customers customer = getAppEng().getUserMgr().getCurrentCustomer();
		try {
			if (customer.getPassword().equals(Encrypt.getHash(oldPass))) {
				customer.setPassword(Encrypt.getHash(newPass));
				customer.save();
				return true;
			}
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public Boolean emailPasswordIfValid(String email) {
		try {
			List<Customers> customers = CustomersPeer.doSelect(new Criteria()
					.add(CustomersPeer.EMAIL_ADDRESS, email));
			if (customers == null || customers.size() < 1)
				return false;
			EmailUsers.sendNewPasswordLink(customers.get(0));
			return true;
		} catch (TorqueException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public ArrayList<GWT_Group> getGroupsByCustomer() {
		try {
			List<GroupMember> groups = GroupMemberPeer.doSelect(new Criteria().add(GroupMemberPeer.MEMBER_ID,getAppEng().getUserMgr().getCurrentCustomer().getCustomersId()));
			ArrayList<GWT_Group> clientGroups = new ArrayList<GWT_Group>();
			for(GroupMember groupMember : groups)
			{
				clientGroups.add(helper.getGWT_Group(groupMember.getGroup()));
			}
			return clientGroups;
		} catch (TorqueException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

}
